package threadx;


import java.util.HashMap;
import java.util.Set;
import java.util.concurrent.ExecutorService;
import java.util.concurrent.Executors;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.ReadLock;
import java.util.concurrent.locks.ReentrantReadWriteLock.WriteLock;

public class Test9 {
    public static ExecutorService e = Executors.newFixedThreadPool(100);

    public static void main(String[] args) {

        RWDictionary rwDictionary = new RWDictionary();

        for (Integer i = 0; i < 100; i++) {
            Integer finalI = i;
            e.submit(new Runnable() {
                @Override
                public void run() {
                    rwDictionary.put(finalI, finalI);
                    System.out.println(Thread.currentThread().getName() + finalI);
                    try {
                        Thread.sleep(8000);
                    } catch (InterruptedException interruptedException) {
                        interruptedException.printStackTrace();
                    }
                }
            });
        }


        for (Integer j = 0; j < 100; j++) {
            Integer finalJ = j;
            e.submit(new Runnable() {
                @Override
                public void run() {


                    System.out.println(Thread.currentThread().getName() +":"+ rwDictionary.get(finalJ).toString());
                }
            });
        }
        e.shutdown();
    }
}


//自定义一个线程安全的HashMap
class RWDictionary {
    private HashMap<Integer, Object> m = new HashMap<Integer, Object>();
    private ReentrantReadWriteLock rwl = new ReentrantReadWriteLock();
    private ReadLock r = rwl.readLock();
    private WriteLock w = rwl.writeLock();

    public Object get(Integer key) {
        r.lock();
        try {
            return m.get(key);
        } finally {
            r.unlock();
        }
    }

    public Set allKeys() {
        r.lock();
        try {
            return m.entrySet();
        } finally {
            r.unlock();
        }
    }

    public Object put(Integer key, Object value) {
        w.lock();
        try {
            return m.put(key, value);
        } finally {
            w.unlock();
        }
    }

    public void clear() {
        w.lock();
        try {
            m.clear();
        } finally {
            w.unlock();
        }
    }
}